<?php
// Copyright 2019 Hackware SpA <human@hackware.cl>
// "Hackware Web Services Core" is released under the MIT License terms.

namespace Hawese\Core\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Database\Query\Builder;
use Illuminate\Validation\ValidationException;
use Laravel\Lumen\Routing\Controller as BaseController;

class Controller extends BaseController
{
    // Right now I don't find any reason to not return the plain object
    protected function singleResponse(object $object): object
    {
        return $object;
    }

    protected function collectionResponse(
        Request $request,
        $model,
        $filters_cb = null
    ) : array {
        $page = $request->query('page', 1);
        $limit = $request->query('limit', 10);
        $sort = $request->query('sort', $model::$primary_key);
        $include = explode(',', $request->query('include'));
        if ($include[0] === '') {
            $include = [];
        }

        if (isset($filters_cb)) {
            $db_query = $filters_cb($model::select());
        } else {
            $db_query = $model::select();
        }

        $sorted_db_query = $this->sortedDbQuery($db_query, $sort, $model);
        $pagination = new Paginator($sorted_db_query, $page, $limit);
        // Turns to 0 after next line, maybe it's worth to debug this
        $total_pages = $pagination->totalPages();
        $collection = $model::processCollection($pagination->get());

        return [
            'meta' => ['total_pages' => $total_pages],
            'data' => $collection->appendForeignObjects($include)->get(),
            'links' => $pagination->links($request->url(), $request->query())
        ];
    }

    private function sortDirection(string $sort_param) : string
    {
        return $sort_param[0] === '-' ? 'desc' : 'asc';
    }

    private function sortedDbQuery(
        Builder $db_query,
        string $sort_param,
        string $model
    ) : Builder {
        return $db_query->orderBy(
            sprintf('%s.%s', $model::$table, trim($sort_param, '-')),
            $this->sortDirection($sort_param)
        );
    }
}
